﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using Org.Alexander.Edas;

namespace TestServer
{
    class Program
    {
        static void Main(string[] args)
        {
            Acceptor acp = new Acceptor(10898);
            acp.ProtocolFactory = new EchoFactory();
            acp.OnStart += new AcceptInfoHandler(acp_OnStart);
            acp.OnStop += new AcceptInfoHandler(acp_OnStop);
            acp.OnSessionStart += new SessionDataHandler(acp_OnSessionStart);
            acp.OnSessionEnd += new AcceptInfoHandler(acp_OnSessionEnd);
            acp.OnError += new AcceptErrorHandler(acp_OnError);
            acp.Start();
            Console.Read();
            acp.Close();
            Console.Read();
            Console.Read();
        }

        static void acp_OnError(string Message, Exception Ex)
        {
            //throw new NotImplementedException();
            Console.WriteLine(Message);
        }

        static void acp_OnSessionEnd(string Message)
        {
            //throw new NotImplementedException();
            Console.WriteLine(Message);
        }

        static void acp_OnSessionStart(Connector Sender)
        {
            //throw new NotImplementedException();
            Console.WriteLine("Session " + Sender.ID + " Start");
        }

        static void acp_OnStop(string Message)
        {
            //throw new NotImplementedException();
            Console.WriteLine(Message);
        }

        static void acp_OnStart(string Message)
        {
            //throw new NotImplementedException();
            Console.WriteLine(Message);
        }
    }

    class EchoFactory : IProtocolFactory
    {

        public IProtocol GetProtocol()
        {
            return new EchoProtocol();
        }
    }

    class EchoProtocol : IProtocol
    {
        public int InitLength
        {
            get;
            set;
        }

        public int HeaderLength
        {
            get;
            set;
        }

        public int BodyLength
        {
            get;
            set;
        }

        public bool IsProcessHeader
        {
            get;
            set;
        }

        public System.IO.MemoryStream IOBuffer
        {
            get;
            set;
        }

        public MemoryStream Package
        {
            get;
            set;
        }

        public byte[] Header
        {
            get;
            set;
        }

        public bool DynamicHeader
        {
            get;
            set;
        }

        public byte[] HandShakeData
        {
            get;
            set;
        }

        public int HandShakeCount
        {
            get;
            set;
        }

        public int[] HandShakeLength
        {
            get;
            set;
        }

        public bool HandShakeOk
        {
            get;
            set;
        }
        public bool HandShakeSendOk
        {
            get;
            set;
        }
        public bool IsSendReply
        {
            get;
            set;
        }
        public bool KeepSending
        {
            get;
            set;
        }

        public ProcessStatus Status
        {
            get;
            set;
        }

        public EchoProtocol()
        {
            HandShakeLength = new int[] { 4, 4, 8};
            //HandShakeOk = true;
            HeaderLength = 1;
            Status = ProcessStatus.HandShake;
        }

        public void OnGetHeader(Connector connector)
        {

            //throw new NotImplementedException();
            if (Header.Length > 0)
            {
                BodyLength = Header[0];
                IsProcessHeader = false;
            }
            //connector.WaitingRead();
        }

        public void OnGetBody(byte[] Package, Connector connector)
        {
            //throw new NotImplementedException();
            string Rs = Encoding.UTF8.GetString(Package, 1, Package.Length - 1);
            Console.WriteLine("Get String " + Rs);
            byte[] rep = Encoding.UTF8.GetBytes("i reply:" + Rs);
            IsSendReply = true;
            connector.Send(rep);
            Console.WriteLine("i reply:" + Rs);
        }

        private int sum = 0;

        public void OnHandShake(Connector connector)
        {
            //throw new NotImplementedException();
            switch (HandShakeCount)
            {
                case 0:
                    if (HandShakeData.Length == 4)
                    {
                        if (HandShakeData[0] == 0x01 && HandShakeData[3] == 0xFF)
                        {
                            Random r = new Random();
                            byte[] s = new byte[4];
                            s[0] = (byte)r.Next(9);
                            s[1] = (byte)r.Next(9);
                            s[2] = (byte)r.Next(9);
                            s[3] = (byte)r.Next(9);
                            sum = s[0] + s[1] + s[2] + s[3];
                            connector.Send(s);
                        }
                        else
                        {
                            connector.Close();
                        }
                    }
                    else
                    {
                        connector.Close();
                    }
                    break;
                case 1:
                    if (HandShakeData.Length == 4)
                    {
                        int i = BitConverter.ToInt32(HandShakeData, 0);
                        if (i == sum)
                        {
                            connector.Send(Encoding.UTF8.GetBytes("Connect ok"));
                        }
                        else
                        {
                            connector.Close();
                        }
                    }
                    else
                    {
                        connector.Close();
                    }
                    break;
                case 2:
                    if (HandShakeData.Length == 8)
                    {
                        long tick = BitConverter.ToInt64(HandShakeData, 0);
                        Console.WriteLine(new DateTime(tick).ToString());
                        connector.Send(Encoding.UTF8.GetBytes("Hands OK"));
                    }

                    break;
            }

        }
        int pc = 0;
        public void OnReplyOk(Connector connector)
        {
            Console.WriteLine("reply send ok!");
            //connector.Close();
            pc++;
            if (pc == 2)
            {
                connector.Close();
            }
        }

        public event PackageDataHandler OnPackageReady;
    }


}
